#include "userMain.h"
#include "userB_IIC.h"
/**********************************************?????***************************************************/

//#define Bx_ASK_Test_Error     

#ifdef  Bx_ASK_Test_Error
#define Bx_ASK_Test_Error
unsigned int Bx_Right_Count = 0;
unsigned int Bx_Error_Count = 0;

#endif

/*IIC time sequence*/
#define     Bx_THD_STA     4            // time of SCL&SDA keep start level 
#define     Bx_TSU_STA     4            //time of SDA start condition
#define     Bx_TYLOW       2            // time of SCL output low level (half of TLOW)
#define     Bx_THIGH       4            //time of SDA output high level
#define     Bx_THHIGN      2            //time of SDA output high level: half
#define     Bx_TSU_STO     4            //time of establish SDA stop condition
#define     Bx_TBUF        8            //time of bus release

#define     Delay_us_2		_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP;_NOP
#define     Delay_us_4		Delay_us_2;Delay_us_2
#define     Delay_us_8		Delay_us_4;Delay_us_4

#define     Dely_us_Bx_THD_STA			Delay_us_4
#define     Dely_us_Bx_TSU_STA			Delay_us_4
#define     Dely_us_Bx_TYLOW			Delay_us_2
#define     Dely_us_Bx_THIGH			Delay_us_4
#define     Dely_us_Bx_THHIGN			Delay_us_2
#define     Dely_us_Bx_TSU_STO			Delay_us_4
#define     Dely_us_Bx_TBUF				Delay_us_8

/***********************************************************************************************************/
/*SDA and SCL IO configure*/
#define     Bx_I2C_SDA_PORT     GPIOB
#define	    Bx_I2C_SDA_PIN	GPIO_Pin_7
#define     Bx_I2C_SCL_PORT     GPIOB
#define	    Bx_I2C_SCL_PIN	GPIO_Pin_6
#define     Bx_SDA_1       	GPIO_SetBits(Bx_I2C_SDA_PORT,Bx_I2C_SDA_PIN)
#define     Bx_SDA_0       	GPIO_ResetBits(Bx_I2C_SDA_PORT,Bx_I2C_SDA_PIN)
#define     Bx_SCL_1            GPIO_SetBits(Bx_I2C_SCL_PORT,Bx_I2C_SCL_PIN)
#define     Bx_SCL_0            GPIO_ResetBits(Bx_I2C_SCL_PORT,Bx_I2C_SCL_PIN)
#define     Bx_SDA_IN           GPIO_ReadInputDataBit(Bx_I2C_SDA_PORT,Bx_I2C_SDA_PIN)
/***********************************************************************************************************/
void Bx_OUT_SDA_config(void);
void Bx_IN_SDA_config(void);
void Bx_OUT_SCL_config(void);
void Bx_IN_SCL_config(void);

void Bx_OUT_SDA_config(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = Bx_I2C_SDA_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(Bx_I2C_SDA_PORT, &GPIO_InitStructure);
}

void Bx_IN_SDA_config(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = Bx_I2C_SDA_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(Bx_I2C_SDA_PORT, &GPIO_InitStructure);
}

void Bx_OUT_SCL_config(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = Bx_I2C_SCL_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(Bx_I2C_SCL_PORT, &GPIO_InitStructure);
}

void Bx_IN_SCL_config(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = Bx_I2C_SCL_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(Bx_I2C_SCL_PORT, &GPIO_InitStructure);
}



/*IIC initial function*/ 
void Bx_IIC_Initial(void)
{
    Bx_OUT_SCL_config(); 
    Bx_OUT_SDA_config();
    Bx_SDA_1;
    Bx_SCL_1;    
  }

/*IIC start function */
void Bx_IIC_Start(void)
{
    Bx_OUT_SDA_config();
    Bx_SCL_1;
    Bx_SDA_1;
  	Dely_us_Bx_TSU_STA;
    Bx_SDA_0;
    Dely_us_Bx_THD_STA;
    Bx_SCL_0;
    Bx_SDA_0;
    Dely_us_Bx_TYLOW;  
  }

/*IIC stop function*/
void Bx_IIC_Stop(void)
{
    Bx_OUT_SDA_config();
    Bx_SCL_0;
    Bx_SDA_0;  
    Dely_us_Bx_TYLOW;  
    Bx_SCL_1;
    Dely_us_Bx_TSU_STO;
    Bx_SDA_1;
    Dely_us_Bx_TBUF;
  }

/*IIC Master ack function*/
/**************************************************/
void Bx_Ack(void)
{
    Bx_OUT_SDA_config();
    Bx_SCL_0;
    Bx_SDA_0;
    Dely_us_Bx_TYLOW;
    Bx_SCL_1;
    Dely_us_Bx_THIGH;
    Bx_SCL_0;
    Dely_us_Bx_TYLOW;
}
/*IIC Master no ack function*/
/*************************************************/
void Bx_NoAck(void)  
{
    Bx_OUT_SDA_config();
    Bx_SCL_0;
    Bx_SDA_1;
    Dely_us_Bx_TYLOW;
    Bx_SCL_1;
    Dely_us_Bx_THIGH;
    Bx_SCL_0;
    Dely_us_Bx_TYLOW;
}
/*IIC Master ack Test function*/
unsigned char Bx_TestAck(void)     
{ 
    int Bx_IIC_ACK_TEST;
    Bx_IN_SDA_config();
    Bx_SCL_0;
    Dely_us_Bx_TYLOW;
    Bx_SCL_1;
    Dely_us_Bx_THIGH;
  
    if(Bx_SDA_IN==0x00)
    {
        Bx_IIC_ACK_TEST=0;
        #ifdef Bx_ASK_Test_Error
        #define Bx_ASK_Test_Error
        Bx_Right_Count++;
        #endif
    }
    else
    {
        Bx_IIC_ACK_TEST=1;
        #ifdef Bx_ASK_Test_Error
        #define Bx_ASK_Test_Error
        Bx_Error_Count++;
        #endif
    }
  
    Bx_SCL_0;
    return Bx_IIC_ACK_TEST;
}
/*write one byte(8 bits)*/
void Bx_Write8Bit(unsigned char Bx_input)
{
    int Bx_temp;
    Bx_OUT_SDA_config();
    for(Bx_temp=8;Bx_temp>0;Bx_temp--)
    {   
        Bx_SCL_0;
        if((Bx_input&0x80)==0)
            Bx_SDA_0;
        else
            Bx_SDA_1;
        Dely_us_Bx_TYLOW;
        Bx_SCL_1; 
        Dely_us_Bx_THIGH;
        Bx_SCL_0;
        Dely_us_Bx_TYLOW;
        Bx_input=Bx_input<<1;
    }
}
/*read one byte (8 bits)*/
/****************************************************/
unsigned char Bx_Read8Bit(void)    
{
    int Bx_temp;
    unsigned char Bx_rbyte=0x00;
    Bx_IN_SDA_config();
    for(Bx_temp=8;Bx_temp>0;Bx_temp--)
    {
        Bx_SCL_0;
        Dely_us_Bx_TYLOW;
        Bx_SCL_1;
        Dely_us_Bx_THHIGN;
        Bx_rbyte=Bx_rbyte<<1;
        if(Bx_SDA_IN==0x00)
            Bx_rbyte=Bx_rbyte|0x00;
        else
            Bx_rbyte=Bx_rbyte|0x01;
        Dely_us_Bx_THHIGN;    
        Bx_SCL_0;
        Dely_us_Bx_TYLOW;
    }
    return(Bx_rbyte);
}
/***********IIC IO Release*********************/
void Bx_IIC_End(void)
{
    Dely_us_Bx_TBUF;
    Bx_IN_SCL_config();
    Bx_IN_SDA_config();
    Dely_us_Bx_TBUF;
}

